﻿using System;
using System.Threading.Tasks;
using Top.Data;
using Top.Web;
using Top.Base.Common;
using System.Diagnostics;
using Top.PointStore.Business.Models;
using System.Collections.Generic;
using Top.Web.Api;
using Top.Business.OAuth;
using Top.Core;

namespace Top.PointStore.Business
{
	/*功能说明:积分操作管理类
	*版本:
	*参与人:王士锋
	*修改日期:2015.3.4
	*/
	/// <summary>
	/// 积分操作类
	/// </summary>
	public static class PointManager
	{
		//-------------------------------------------------------------获取积分-----------------------------------------------------------------------------
		public static async Task<T_PointMain_new> Get(string userToken)
		{
			T_PointMain_new model = new T_PointMain_new();
			if (string.IsNullOrWhiteSpace(userToken)) return model;
			try
			{
				using (var db = DataBase.Reader())
				{
					const string sql = @"select * from T_PointMain_new   where F_UserToken = {0} limit 1";
					T_PointMain_new resultModel = await db.Sql(sql, userToken).FirstOrDefault<T_PointMain_new>();
					if (resultModel != null)
					{
						model = resultModel;
					}
				}
			}
			catch (Exception ex)
			{
				Trace.TraceError(string.Format("类名[PointManager] 方法名[Get] 经纪人KID[{1}] 异常信息：{0}", ex.ToString(), userToken));
			}
			return model;
		}

		public static async Task<T_PointMain_new> GetV2(OAuthUser user)
		{
			T_PointMain_new model = new T_PointMain_new();
			if (user == null) return model;
			try
			{
				using (var db = new DbTour())
				{
					model = await PointManager.Get(user.UserToken.ToString());
					if (model != null && string.IsNullOrWhiteSpace(model.F_UserToken))
					{
						T_PointMain_new pointMain = new T_PointMain_new()
						{
							F_UserToken = user.UserToken.ToString(),
							F_PointAll = 0,
							F_PointBalance = 0,
							F_PointCash = 0
						};
						int kid = await PointManager.Add(pointMain);
						pointMain.Kid = kid;
						return pointMain;
					}
				}
			}
			catch (Exception ex)
			{
				Trace.TraceError(string.Format("类名[PointManager] 方法名[Get] 经纪人KID[{1}] 异常信息：{0}", ex.ToString(), user.UserToken));
			}
			return model;
		}

        //public static async Task<T_PointMain_new> GetV3(int userKid, string accessToken, string userToken)
        //{
        //    OAuthUser userInfo = default(OAuthUser);
        //    if (string.IsNullOrWhiteSpace(accessToken))
        //    {
        //        if (string.IsNullOrWhiteSpace(userToken))
        //        {
        //            if (userKid == 0)
        //            {
        //                throw new WebApiException("缺少关键信息，无法找到该用户");
        //            }
        //            else
        //            {
        //                Guid token = OAuthHelper.GetTokenByAdminKid await OAuth.GetAdminToken(userKid);
        //                userInfo = await OAuth.GetUserInfo(token);
        //            }
        //        }
        //        else
        //        {
        //            userInfo = await OAuth.GetUserInfo(Convert3.To<Guid>(userToken));
        //        }
        //    }
        //    else
        //    {
        //        userInfo = await OAuth.GetUser(Convert3.To<Guid>(accessToken));
        //    }
        //    if (userInfo == null)
        //    {
        //        throw new WebApiException("无法找到该用户OAuth信息");
        //    }
        //    T_PointMain_new userPointInfo = GlobalResourceManager.GetMyPoint(userInfo);
        //    if (userPointInfo == null)
        //    {
        //        return await GetV2(userInfo);
        //    }
        //    return userPointInfo;
        //}

        //public static async Task<T_PointMain_new> GetV4(int userKid, string accessToken, string userToken)
        //{
        //    OAuthUser userInfo = default(OAuthUser);
        //    if (string.IsNullOrWhiteSpace(accessToken))
        //    {
        //        if (string.IsNullOrWhiteSpace(userToken))
        //        {
        //            if (userKid == 0)
        //            {
        //                throw new WebApiException("缺少关键信息，无法找到该用户");
        //            }
        //            else
        //            {
        //                Guid token = await OAuth.GetBrokerToken(userKid);
        //                userInfo = await OAuth.GetUserInfo(token);
        //            }
        //        }
        //        else
        //        {
        //            userInfo = await OAuth.GetUserInfo(Convert3.To<Guid>(userToken));
        //        }
        //    }
        //    else
        //    {
        //        userInfo = await OAuth.GetUser(Convert3.To<Guid>(accessToken));
        //    }
        //    if (userInfo == null)
        //    {
        //        throw new WebApiException("无法找到该用户OAuth信息");
        //    }
        //    T_PointMain_new userPointInfo = GlobalResourceManager.GetMyPoint(userInfo);
        //    if (userPointInfo == null)
        //    {
        //        return await GetV2(userInfo);
        //    }
        //    return userPointInfo;
        //}

        //public static async Task<IList<T_PointMain_new>> GetAll()
        //{
        //    List<T_PointMain_new> model = new List<T_PointMain_new>();
        //    try
        //    {
        //        using (var db = DataBase.Reader())
        //        {
        //            const string sql = @"select * from T_PointMain_new  ";
        //            var resultModel = await db.Sql(sql).ToList<T_PointMain_new>();
        //            if (resultModel != null)
        //            {
        //                model = resultModel;
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Trace.TraceError(string.Format("类名[PointManager] 方法名[GetAll]  异常信息：{0}", ex.ToString()));
        //    }
        //    return model;
        //}

		public static async Task<IList<BorkerKid_Point>> GetAssignPoint(string kids)
		{
			List<BorkerKid_Point> model = new List<BorkerKid_Point>();
			try
			{
				using (var db = DataBase.Reader())
				{
					string sql = @"select b.F_BrokerKid as BrokerKid,a.F_PointAll as Point from T_PointMain_new a left join T_OAuthInfo b on a.F_UserToken=b.F_UserToken
where F_BrokerKid>0 and F_BrokerKid in (" +kids+")";
					var resultModel = await db.Sql(sql).ToList<BorkerKid_Point>();
					if (resultModel != null)
					{
						model = resultModel;
					}
				}
			}
			catch (Exception ex)
			{
				Trace.TraceError(string.Format("类名[PointManager] 方法名[GetAll]  异常信息：{0}", ex.ToString()));
			}
			return model;
		}
		//--------------------------------------------------------------修改积分（数据库、内存）----------------------------------------------------------------------------
		public static async Task<int> SuperInterface_ChangePoint(OAuthUser user, T_PointMain_new pointMain)
		{
			GlobalResourceManager.UpdateMyPoint_Memory(user, pointMain);
			using (var db = new DbTour())
			{
				const string sql = @"update T_PointMain_new set F_PointBalance={0:F_PointBalance},F_PointCash={0:F_PointCash},F_PointAll={0:F_PointAll} where F_UserToken={0:F_UserToken}";
				return await db.Sql(sql, pointMain).ExecuteNonQuery();
			}
		}

        //public static async Task<int> SuperInterface_ChangePoint(string userToken, T_PointMain_new pointMain)
        //{
        //    OAuthUser user = await OAuth.GetUserInfo(Convert3.To<Guid>(userToken));
        //    GlobalResourceManager.UpdateMyPoint_Memory(user, pointMain);
        //    using (var db = new DbTour())
        //    {
        //        const string sql = @"update T_PointMain_new set F_PointBalance={0:F_PointBalance},F_PointCash={0:F_PointCash},F_PointAll={0:F_PointAll} where F_UserToken={0:F_UserToken}";
        //        return await db.Sql(sql, pointMain).ExecuteNonQuery();
        //    }
        //}

		public static async Task<int> SuperInterface_ChangePoint(OAuthUser user, T_PointMain_new pointMain, DbTour db)
		{
			GlobalResourceManager.UpdateMyPoint_Memory(user, pointMain);
			const string sql = @"update T_PointMain_new set F_PointBalance={0:F_PointBalance},F_PointCash={0:F_PointCash},F_PointAll={0:F_PointAll} where F_UserToken={0:F_UserToken}";
			return await db.Sql(sql, pointMain).ExecuteNonQuery();
		}

        //public static async Task<int> SuperInterface_ChangePoint(string userToken, T_PointMain_new pointMain, DbTour db)
        //{
        //    OAuthUser user = await OAuth.GetUserInfo(Convert3.To<Guid>(userToken));
        //    GlobalResourceManager.UpdateMyPoint_Memory(user, pointMain);
        //    const string sql = @"update T_PointMain_new set F_PointBalance={0:F_PointBalance},F_PointCash={0:F_PointCash},F_PointAll={0:F_PointAll} where F_UserToken={0:F_UserToken}";
        //    return await db.Sql(sql, pointMain).ExecuteNonQuery();
        //}

		public static async Task<int> SuperInterface_ChangePoint(T_PointMain_new pointMain, DbTour db)
		{
            OAuthUser user = OAuthHelper.GetUser(pointMain.F_UserToken);// await OAuth.GetUserInfo(Convert3.To<Guid>(pointMain.F_UserToken));
			GlobalResourceManager.UpdateMyPoint_Memory(user, pointMain);
			const string sql = @"update T_PointMain_new set F_PointBalance={0:F_PointBalance},F_PointCash={0:F_PointCash},F_PointAll={0:F_PointAll} where F_UserToken={0:F_UserToken}";
			return await db.Sql(sql, pointMain).ExecuteNonQuery();
		}

		//--------------------------------------------------------------更新积分（方法）------------------------------------------------------------------------------------------       
		public static async Task<int> UpdateUserPoint(string userToken, int point, string remark, DbTour db, T_PointMain_new pointMain = null)
		{
			if (pointMain == null)
			{
				bool isExist = MemoryTable.TB_PointMain_new.ContainsKey(userToken.ToUpper());
				if (isExist)
				{
					pointMain = MemoryTable.TB_PointMain_new[userToken.ToUpper()];
				}
				else
				{
					pointMain = await PointManager.Get(userToken);
				}
				if (pointMain == null) return -1;
			}

			//TODO 积分更新有问题 待确认
			if (point > 0)
			{
				pointMain.F_PointAll += point;
				pointMain.F_PointBalance += point;
			}
			if (point < 0)
			{
				if (pointMain.F_PointBalance < -point)
				{
					return -4; //无购买能力
				}
				pointMain.F_PointBalance += point;
				pointMain.F_PointCash += -point;
			}
			int resultID = await SuperInterface_ChangePoint(pointMain, db);
			if (resultID > 0)
			{
				await PointDetailManager.AddPoint(pointMain, point, remark);
			}
			return resultID;
		}

		public static async Task<int> UpdateUserPoint(string userToken, int point, string pointCode, int productsExchangeKid, string behavior, DbTour db)
		{
			T_PointMain_new pointMain = new T_PointMain_new();
			bool isExist = MemoryTable.TB_PointMain_new.ContainsKey(userToken.ToUpper());
			if (isExist)
			{
				pointMain = MemoryTable.TB_PointMain_new[userToken.ToUpper()];
			}
			else
			{
				pointMain = await PointManager.Get(userToken);
			}
			if (pointMain == null) return -1;

			switch (behavior)
			{
				case "ADD": //加积分    
					point = Math.Abs(point);
					pointMain.F_PointBalance += point;
					pointMain.F_PointAll += point;
					break;
				case "SUBTRACT": //减积分
					point = Math.Abs(point);
					if (point > pointMain.F_PointBalance)
					{
						return -4;//积分不足
					}
					pointMain.F_PointBalance -= point;
					pointMain.F_PointCash += point;
					break;
				case "REFUND": //退还积分
					point = Math.Abs(point);
					if (point > pointMain.F_PointCash)
					{
						return -11;//退还积分超过已兑换积分
					}
					pointMain.F_PointBalance += point;
					pointMain.F_PointAll += point;
					pointMain.F_PointCash -= point;
					break;
				default:
					return await UpdateUserPoint(userToken, point, pointCode, db);
			}           
			int resultID = await SuperInterface_ChangePoint(pointMain, db);
			if (resultID > 0)
			{
				switch (behavior)
				{
					case "ADD"://AddPoint(int userKid, int point, string remark,DbTour db)
						await PointDetailManager.AddPoint(pointMain, point, pointCode);
						break;
					case "SUBTRACT":
						await PointDetailManager.AddPoint(pointMain, -point, pointCode, productsExchangeKid, db);
						break;
					case "REFUND":
						await PointDetailManager.AddPoint(pointMain, point, pointCode, productsExchangeKid, db);
						break;
				}
			}
			return resultID;
		}

		public static async Task<int> UpdateUserPoint(string userToken, int point, string pointCode)
		{
			try
			{
				using (var db = new DbTour())
				{
					return await PointManager.UpdateUserPoint(userToken, point, pointCode, db);
				}
			}
			catch (Exception ex)
			{
				ErrorLog.WriteLog(ex);
				return -2;
			}
		}





		/// <summary>
		/// 添加用户积分统计
		/// </summary>
		/// <param name="pointMain"></param>
		/// <returns></returns>
		public static async Task<int> Add(T_PointMain_new pointMain)
		{

			using (var db = new DbTour())
			{
				const string sql = @"INSERT INTO T_PointMain_new(F_UserToken,F_PointAll,F_PointCash,F_PointBalance)
	 VALUES({0:F_UserToken},{0:F_PointAll},{0:F_PointCash},{0:F_PointBalance});SELECT LAST_INSERT_ID();";
				return await db.Sql(sql, pointMain).ExecuteScalar<int>();
			}
		}

		/// <summary>
		/// 积分添加 接入点有： 签到、 推客、 带看（扫一扫&申请带看成功）、 成交（申请成交确认，只加经纪人的积分）
		/// </summary>
		/// <param name="pointCode">积分规则：每日签到(api.all.signin)、经纪人推荐客户(weixin.customer.push)、 微经纪客户确认带看(weixin.broker.apply.confirm.look) 微经纪带看扫码(weixin.allocation.intent.log) 微经纪客户确认成交(weixin.broker.apply.confirm.business)</param>
		/// <param name="buildingKid">楼盘</param>
		/// <param name="brokerKid">经纪人账号ID</param>
		/// <param name="adminKid">楼盘账号ID</param>
		/// <param name="userToken">用户标示</param>
		/// <param name="pointSource">积分来源APP：500，微信：400, WEB:300,二手房：200</param>
		/// <returns>获得的积分</returns>
		///  DateTime.Now.AddDays(-1)
		public static async Task<int> SubmitPoint(string pointCode, int buildingKid, int pointSource, OAuthUser user, T_PointMain_new pointMain,bool isClub=false)
		{
			try
			{
                //判断用户是否在黑名单
                if(await BlacklistManager.Exist(user.BrokerID))
                {
                    return 0;
                }
				// 规则是否存在
				T_PointRule rule = await PointRuleManager.Get(pointCode);
				if (rule == null)
				{
					return -1;
				}

				#region 积分活动判断

				DateTime startDate = DateTime.Now;
				DateTime endDate = DateTime.Now.AddDays(-1);

				T_PointSetting setting;
                if (!isClub)
                {
                    using (var db = DataBaseContext.GetDataBase("sqldefault"))
                    {
                        setting = await PointSettingManager.Get(pointCode, buildingKid, startDate, endDate, 0, db);
                        var buildingModel = await BuildingManager.GetBuilding(buildingKid, db);
                        if (buildingModel != null && buildingModel.F_IsTest == 1)
                        {
                            return 1;
                        }
                        if (buildingModel != null)
                        {
                            //单个楼盘全部行为
                            if (setting == null)
                            {
                                setting = await PointSettingManager.Get("", buildingKid, startDate, endDate, 0, db);
                            }
                            //全部楼盘单个行为
                            if (setting == null)
                            {
                                setting = await PointSettingManager.Get(rule.F_PointCode, 0, endDate, endDate, buildingModel.F_CityKid, db);
                            }
                            //全部楼盘全部行为
                            if (setting == null)
                            {
                                setting = await PointSettingManager.Get("", 0, endDate, endDate, buildingModel.F_CityKid, db);
                            }
                        }
                    }
                }
                else
                {
                    setting = null;
                }
				
				
				#endregion

				//添加积分及积分详细
				var detail = new T_PointDetail();
				detail.F_AddTime = DateTime.Now;
				detail.F_BuildingKid = buildingKid;
				detail.F_PointCode = rule.F_PointCode;
				detail.F_PointId = pointMain.Kid;
				detail.F_PointSource = pointSource;
				detail.F_Point = rule.F_Point;

				if (setting == null || setting.F_Multiple < 2)
				{
					if (rule.F_Point > 0)
					{
						pointMain.F_PointAll += rule.F_Point;
					}
					else
					{
						pointMain.F_PointCash += -rule.F_Point;
					}
					pointMain.F_PointBalance += rule.F_Point;
				}
				else
				{
					detail.F_Point = detail.F_Point * setting.F_Multiple;
					pointMain.F_PointAll += detail.F_Point;
					pointMain.F_PointBalance += detail.F_Point;
				}

				detail.F_PointId = pointMain.Kid;

				if (pointMain.F_PointBalance <= 0)
				{
					pointMain.F_PointBalance = 0;
				}

				using (var db = DataBaseContext.GetDataBase("default"))
				{
					await PointManager.SuperInterface_ChangePoint(user, pointMain, db);
				}
				await PointDetailManager.Add(detail);
				return 1;
			}
			catch (Exception ex)
			{
				ErrorLog.WriteLog(ex);
				return -1;
			}
		}

		/// <summary> 获取OAuthInfo 信息[针对从未操作过积分商城，首次拉取用户的信息]
		/// </summary>
		/// <param name="userToken"></param>
		/// <returns></returns>
        //public static async Task<bool> AddOAuthInfo(Guid userToken, OAuthUser OAuthUser = null)
        //{
        //    if (OAuthUser == null)
        //    {
        //        OAuthUser = await OAuth.GetUserInfo(userToken);
        //    }
        //    using (var db = new DbTour())
        //    {
        //        string sqlInsert = "insert T_OAuthInfo(F_UserToken,F_BrokerKid,F_AdminKid) values({0},{1},{2})";
        //        return await db.Sql(sqlInsert, OAuthUser.UserToken, OAuthUser.BrokerID, OAuthUser.CrmUserID).ExecuteNonQuery() > 0;
        //    }
        //}

		/// <summary>
		/// 根据用户ID获取userToken
		/// </summary>
		/// <param name="userKid"></param>
		/// <returns></returns>
		public static async Task<string> GetUserToken(int brokerKid, int adminKid)
		{
			using (var db = new DbTour())
			{
				if (brokerKid > 0)
				{
					const string sql = "select F_UserToken from t_OAuthInfo   where F_BrokerKid={0}";
					return await db.Sql(sql, brokerKid).ExecuteScalar<string>();
				}
				else
				{
					const string sql = "select F_UserToken from t_OAuthInfo   where F_AdminKid={0}";
					return await db.Sql(sql, adminKid).ExecuteScalar<string>();
				}
			}
		}

		public static async Task<object> UserSignIn(OAuthUser user, T_PointMain_new pointMain, string pointCode = "")
		{
			Model_SignIn signInModel = new Model_SignIn();
			signInModel = await CheckTodaySignState(user.UserToken.ToString(), pointCode);

			if (signInModel != null)
			{
				var res = new
				{
					IsSignIn = 1,
					PointAll = signInModel.F_PointBalance,
					Description = "已签到"
				};
				return res;
			}

			// 规则是否存在
			T_PointRule rule = await PointRuleManager.Get(pointCode);
			if (rule == null)
			{
				throw new WebApiException("签到规则未开启");
			}
			using (var db = new DbTour())
			{
				await UpdateUserPoint(user.UserToken.ToString(), rule.F_Point, pointCode, db, pointMain);
			}
			var res2 = new
			{
				IsSignIn = 1,
				PointAll = pointMain.F_PointBalance,
				Description = "签到成功"
			};
			return res2;
		}

		public static async Task<object> CheckSignIn(OAuthUser user, string pointCode = "")
		{
			Model_SignIn signInModel = new Model_SignIn();
			signInModel = await CheckTodaySignState(user.UserToken.ToString(), pointCode);
			if (signInModel == null)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		public static async Task<Model_SignIn> CheckTodaySignState(string userToken = "", string pointCode = "")
		{
			Model_SignIn signInModel = null;
			using (var db = new DbTour())
			{
				string sql = @"
								select 
									 a.F_AddTime as LastSignInTime,
									 b.F_PointBalance as F_PointBalance
								from T_PointDetail_new  a  
									left join T_PointMain_new b   on a.F_PointId=b.Kid
								where 1=1	                                
									and b.F_UserToken={0}
									and a.F_PointCode={1}
									and a.F_AddTime>{2}
								order by a.F_AddTime desc
								limit 1
								";
				signInModel = await db.Sql(sql, userToken, pointCode, DateTime.Now.Date.ToString("yyyy-MM-dd")).FirstOrDefault<Model_SignIn>();
			}
			return signInModel;
		}


		public static async Task<PagedList<UserPointMain>> GetUserPointMain(string userPhone,Pager pager)
		{
			using (var db = DataBaseContext.GetDataBase("reader"))
			{
//                var query = db.Table(@"
//					select 
//					  '经纪人' as F_UserType,
//					  a.F_Title as F_UserName,
//					  a.F_Phone as F_UserPhone,
//					  e.F_Title as F_CompanyName,
//					  c.F_Name as F_CityName,
//					  d.F_PointAll,
//					  d.F_PointBalance,
//					  d.F_PointCash,
//					  b.F_UserToken,
//					  d.Kid as PointId
//					from T_Broker a  
//					  left join T_BrokerCompany e on a.F_BrokerCompanyKid = e.kid
//					  left join T_OAuthInfo b   on a.Kid=b.F_BrokerKid
//					  left join T_ProvinceCityArea c on a.F_CityKid=c.Kid
//					  left join T_PointMain_new d   on b.F_UserToken=d.F_UserToken
//				");
//                query.And("b.F_UserToken IS NOT NULL");
                var query = db.Table(@"select * from v_brokerpoint");
				if (!string.IsNullOrWhiteSpace(userPhone))
				{
					query.And("F_UserPhone={0}", userPhone);
				}
				return await query.ToPagedList<UserPointMain>(pager.StartNumber, pager.EndNumber);
			}
		}

		public static async Task<int> SetUserPointMain(int pointAll, int pointBalance, int pointCash, string userToken)
		{
			try
			{
				T_PointMain_new pointMain = await PointManager.Get(userToken);
				int differenceValue = pointBalance - pointMain.F_PointBalance;
				string sql = @"
				UPDATE T_PointMain_new
				SET F_PointAll={0},
					F_PointBalance={1},
					F_PointCash={2}
				WHERE F_UserToken={3}
				";
				using (var db = new DbTour())
				{
					int result = 0;
					result = await db.Sql(sql, pointAll, pointBalance, pointCash, userToken).ExecuteNonQuery();
					await PointDetailManager.AddPoint(pointMain, differenceValue, "api.point.admin.operate");
					return result;
				}
			}
			catch (Exception ex)
			{
				throw new WebApiException("操作失败，请联系技术人员");
			}

		}

		public static async Task<int> GetTodayPoint(T_PointMain_new pointMain)
		{
			int todayPoint = 0;
			string sql = @"
			select IFNULL(SUM(F_Point),0) AS TodayPoint
			from T_PointDetail_new 
			where 1=1
			and F_PointId={0}
			and F_AddTime>={1}
			";
			using (var db = DataBaseContext.GetDataBase("reader"))
			{
				todayPoint = await db.Sql(sql, pointMain.Kid, DateTime.Now.Date).FirstOrDefault<int>();
			}
			return todayPoint;
		}
	}
	public class UserPointMain
	{
		public string F_UserType { get; set; }
		public string F_UserName { get; set; }
		public string F_UserPhone { get; set; }
		public string F_CompanyName { get; set; }
		public string F_CityName { get; set; }
		public string F_PointAll { get; set; }
		public string F_PointBalance { get; set; }
		public string F_PointCash { get; set; }
		public string F_UserToken { get; set; }
		public int PointId { get; set; }
	}

	public class BorkerKid_Point
	{
		public int BrokerKid { get; set; }

		public int Point { get; set; }
	}
}
